package cn.ycc1.functionlibrary.reflection;

/**
 * Reading Modifiers
 * @author ycc
 * @date 2025/3/9
 * Many elements have modifiers in the Java language: classes, fields, methods, constructors, or method and constructor
 * parameters. These modifiers can modify the visibility of the element there are applied to, or the fact that they can be
 * overridden, or made non-modifiable. The Reflection API gives access to these modifiers, once you have a reference on the element you need to query.
 */
public class ReadingModifiers {
    /**
     * Using getModifiers()
     * A class or class member may be declared with one or more modifiers which affect its runtime behavior:
     *
     * Access modifiers: public, protected, and private
     * Modifier requiring override: abstract
     * Modifier restricting override: sealed, non-sealed
     * Modifier restricting to one instance: static
     * Modifier prohibiting value modification or extension: final
     * Modifier forcing strict floating point behavior: strictfp
     * Annotations
     * Not all modifiers are allowed on all classes or all members, for example an interface cannot be final and an enum cannot
     * be abstract. The class java.lang.reflect.Modifier contains declarations for some possible modifiers (it does not contain
     * sealed and non-sealed). It also contains methods which may be used to decode the set of modifiers returned by the method
     * [Class.getModifiers()`](javadoc:Class.getModifiers()).
     *
     * You can get the modifiers of a class by calling its getModifiers() method. This method returns an int, in which each bit
     * represents a modifier. For instance, if the bit 0 is set, it means that the corresponding member is public. If the bit 3
     * is set, then the corresponding member is static.
     *
     * Having to decode the modifiers int would be cumbersome. Fortunately, the class Modifier is there to help you. This class
     * provides a collection of static methods, one for each modifier, that decodes this integer for you.
     *
     * Let us see this method in action on two examples.
     *
     * Class<?> s = String.class;
     * int modifiers = s.getModifiers();
     * System.out.println("Is String final? " + Modifier.isFinal(modifiers));
     * System.out.println("Is String abstract? " + Modifier.isAbstract(modifiers));
     * The previous code prints the following:
     *
     * Is String final? true
     * Is String abstract? false
     * Indeed, the String class is final, and non-abstract.
     *
     * You can run the same code on the Collection interface.
     *
     * Class<?> c = Collection.class;
     * modifiers = c.getModifiers();
     * System.out.println("Is Collection final? " + Modifier.isFinal(modifiers));
     * System.out.println("Is Collection abstract? " + Modifier.isAbstract(modifiers));
     * The previous code prints the following:
     *
     * Is Collection final? false
     * Is Collection abstract? true
     * Since Collection is an interface, it is implicitly abstract. The compiler adds this modifier for every interface.
     */

    /**
     * The Member Interface
     * There are two declarations of this getModifiers() method:
     *
     * one on the Class class,
     * and another one on the Member interface, that is implemented by the following classes: Field, Method, and Constructor.
     * Both methods work in the same way: they return the same int that you need to decode using the factory methods of the
     * Modifier class.
     */

    /**
     * Access Flags
     * Both the Class class and the Member interface saw the addition of an accessFlags() method in Java SE 20. This method
     * returns a set of AccessFlag instances, that makes the reading of modifiers easier.
     *
     * AccessFlag is an enumeration that defines the modifiers you can add on a class, a field, a method, or a constructor.
     *
     * You can see access flags in action on the following example.
     *
     * Class<?> c = String.class;
     * Set<AccessFlag> accessFlags = c.accessFlags();
     * for (AccessFlag accessFlag : accessFlags) {
     *     System.out.println("accessFlag = " + accessFlag);
     * }
     * Running the previous example gives you the following result.
     *
     * accessFlag = PUBLIC
     * accessFlag = FINAL
     * accessFlag = SUPER
     * Note that some modifiers and access flags have a one-to-one correspondence, but not all of them. You can get more
     * information on this point in the documentatoin of the AccessFlag enumeration.
     */


}
